<?php

namespace zhtfrontend\controllers;

use common\components\extenders\AjaxObject;
use yii\db\Query;
use zhtfrontend\models\datas\AuthItem;
use zhtfrontend\models\forms\RoleForm;
use common\components\helpers\Fun;
use common\components\helpers\Util;
use common\components\helpers\Tree;
use common\models\datas\Menu;
use yii\web\BadRequestHttpException;
use yii\web\Response;

class RoleController extends \zhtfrontend\components\bases\BaseController
{
    public $str='';

    public $index=0;

    public function actionIndex()
    {
        $model = AuthItem::find()->orderBy('created_at ASC')->where(['type'=>1])->asArray()->all();
        return $this->render('index',['model'=>$model]);
    }

    public function actionCreate(){//添加authitem表
        $this->layout='@app/views/layouts/iframe.php';
        $model=new RoleForm();
        $model->scenario='create';
        if($model->load(\Yii::$app->request->post()) && $model->validate()){
            $auth = \Yii::$app->authManager;
            $role=$auth->createRole($model->name);//创建一个角色对象
            $role->description=$model->description;
            if($auth->add($role)){//添加到基于角色的访问控制系统
                return $this->redirectMessage(\Yii::t('zhtfrontend','角色添加成功'),Fun::url('role/index'));
            }
        }
        return $this->render('create',['model'=>$model]);


    }

    public function actionUpdate(){//添加authitem表
        $this->layout='@app/views/layouts/iframe.php';
        if(empty($_GET['name'])){//如果角色名称不为空
            throw new BadRequestHttpException(\Yii::t('zhtfrontend','角色不存在'));
        }
        $model=new RoleForm();
        $auth = \Yii::$app->authManager;
        $role= $auth->getRole($_GET['name']);//根据角色名得到相应的角色对象
        $model->name=$role->name;
        $model->description=$role->description;
        if($model->load(\Yii::$app->request->post())&&$model->validate()){
            $role->description=$model->description;
            $auth->update($role->name,$role);//更新角色对象
            return $this->redirectMessage(\Yii::t('zhtfrontend','角色修改成功'),Fun::url('role/index'));
        }
        return $this->render('update',['model'=>$model]);
    }

    /*
     * 为当前角色添加规则约束
     */
    public function actionRulepermission(){
        $this->layout = '@app/views/layouts/iframe.php';
        if (\Yii::$app->request->get('name') == null){
            throw new BadRequestHttpException(\Yii::t('zhtfrontend','角色不存在'));
        }
        /*
         * 获取这个角色拥有的规则
         * 1. 所有规则，获取已有规则，已有规则放到右侧，其余的放到左侧
         */
        $role_name = \Yii::$app->request->get('name');
        $auth = \Yii::$app->authManager;
        $rules_arr=[];
        $rules = $auth->getRules();
        foreach ($rules as $r){
            $rules_arr[] = $r->name;
        }
        $rule_permission_name = (new Query())->select('ai.name')->from('{{%auth_item}} ai')->where(['in', 'ai.rule_name', $rules_arr])->column(Fun::getSiteDb());
        $had_rulepermission_name = (new Query())->select('aic.child')->from('{{%auth_item_child}} aic')->where(['in', 'aic.child', $rule_permission_name])->andWhere('aic.parent=:parent', [':parent' => $role_name])->column(Fun::getSiteDb());
        $data = [
            'avaliable' => array_diff($rules_arr,$had_rulepermission_name),
            'assigned'=>$had_rulepermission_name
        ];

        return $this->render('rulepermission',['data'=>$data,'role_name'=>$role_name]);
    }

    public function actionAssignrule(){
        if (\Yii::$app->request->isAjax) {
            \Yii::$app->response->format = Response::FORMAT_JSON;
            $auth = \Yii::$app->authManager;
            if(\Yii::$app->request->post('ajax') == 'addrulepermission'){
                $ajaxObject = new AjaxObject();
                $rule_permission_name = \Yii::$app->request->post('rule_permission');
                $role_name = \Yii::$app->request->post('role_name');
                if(!empty($rule_permission_name) && !empty($role_name)){
                    //将规则作用的菜单从角色中剔除出来，然后将规则绑到角色中去
                    $rule_childspermission = $auth->getChildren($rule_permission_name);
                    $role = $auth->getRole($role_name);
                    foreach ($rule_childspermission as $rch){
                        $auth->removeChild($role,$rch);
                    }
                    $rulepermission = $auth->getPermission($rule_permission_name);
                    $auth->addChild($role,$rulepermission);
                    $ajaxObject->content = "success";
                }else{
                    $ajaxObject->content = "fail";
                }
                return $ajaxObject;
            }elseif (\Yii::$app->request->post('ajax') == 'removerulepermission'){
                $ajaxObject = new AjaxObject();
                $rule_permission_name = \Yii::$app->request->post('rule_permission');
                $role_name = \Yii::$app->request->post('role_name');
                if(!empty($rule_permission_name) && !empty($role_name)){
                    /*
                     * 获取规则名下的菜单权限，移除规则权限后将规则名下的菜单权限添加上去
                     * em……好像不对，这个菜单如果被其他规则占用的话是不能添加的，是这样添加上呢还是要用户到菜单上添加呢，自己添加可以免得写代码，万一后期一对一的规则就更没有必要写了
                     */
                    $role = $auth->getRole($role_name);
                    $rulepermission = $auth->getPermission($rule_permission_name);
                    $auth->removeChild($role,$rulepermission);

                    $rules_arr=[];
                    $rules = $auth->getRules();
                    foreach ($rules as $r){
                        $rules_arr[] = $r->name;
                    }
                    $rule_permission_name = (new Query())->select('ai.name')->from('{{%auth_item}} ai')->where(['in', 'ai.rule_name', $rules_arr])->column(Fun::getSiteDb());
                    $had_rulepermission_name = (new Query())->select('aic.child')->from('{{%auth_item_child}} aic')->where(['in', 'aic.child', $rule_permission_name])->andWhere('aic.parent=:parent', [':parent' => $role_name])->column(Fun::getSiteDb());

                    $had_menu_permissions = [];
                    foreach ($had_rulepermission_name as $hr){
                        $ch = $auth->getChildren($hr);
                        $had_menu_permissions = array_merge($had_menu_permissions,$ch);
                    }
                    $rule_childspermission = $auth->getChildren($rule_permission_name);

                    //$role_hadpermissions = $auth->getPermissionsByRole($role_name);
                    foreach ($rule_childspermission as $rpm){
                        if(!in_array($rpm,$had_menu_permissions)){
                            if(!$auth->canAddChild($role,$rpm)){
                                $auth->addChild($role,$rpm);
                            }
                        }
                    }

                    $ajaxObject->content = "success";
                }else{
                    $ajaxObject->content = "fail";
                }
                return $ajaxObject;
            }
        }
    }
    public function actionDelete()
    {
        if(empty($_GET['name'])){
            throw new BadRequestHttpException(\Yii::t('zhtfrontend','角色不存在'));
        }
        $auth = \Yii::$app->authManager;
        $role=$auth->getRole($_GET['name']);
        if($auth->remove($role)){//删除角色
            return $this->redirectMessage(\Yii::t('zhtfrontend', '信息删除成功'), Fun::url(['role/index']));
        }
    }

    public function actionSetaccess(){//设置角色权限
        if(empty($_GET['name'])){
            throw new BadRequestHttpException(\Yii::t('zhtfrontend','角色不存在'));
        }
        $auth = \Yii::$app->authManager;//返回这次应用的权限管理员
        $role=$auth->getRole($_GET['name']);

        if($role===null){
            throw new BadRequestHttpException(\Yii::t('zhtfrontend','角色不存在'));
        }
        $permissions=$auth->getPermissionsByRole($_GET['name']);//返回该角色对应的所有操作
//        Fun::setSiteDatabases();
        $parent=Menu::find()->where(['module'=>'branch','parent_id'=>0])->andWhere(['>','display',0])->indexBy('id')->orderBy('listorder ASC,id ASC')->asArray()->all();
        $menu_list=Menu::find()->where(['module'=>'branch'])->andWhere(['>','display',0])->indexBy('id')->orderBy('listorder ASC,id ASC')->all();
        $menu_array=[];
        foreach ($menu_list as $k=>$v){
            $menu_array[$k]['id']=$v->id;
            $menu_array[$k]['input']=in_array($this->__getPermission($v->id),$permissions);//返回选择框，in_array($this->__getPermission($v->id),$permissions)判断是否已设置该权限
            $menu_array[$k]['parent_id']=$v->parent_id;
            $menu_array[$k]['name']=$v->name;
        }
        $array=[];
        foreach($parent as $k=>$v){
            $this->str='';
            $data[0]=$menu_array[$k];
            $data[0]['level']=1;
            $data[0]['tt-parent-id']='';
            $data[0]['children']=(new Tree($menu_array))->get_jquery_tree_array($k,1);
            $array[$k]=$this->_getTree($data);
        }
        if(\Yii::$app->request->isAjax && \Yii::$app->request->post('ajax') == 'set'){
            \Yii::$app->response->format = Response::FORMAT_JSON;
            $check_id=\Yii::$app->request->post('checked');
            $check_id = explode(",", $check_id);
            $auth->removeChildren($role);//移除子类与父类之间的关系，the children items are not deleted. Only the parent-child relationships are removed.
            foreach($check_id as $id){
                $id=(int)$id;
                if($id>0) {
                    $permission = $this->__getPermission($id);//增加子类与父类的关系
                    $auth->addChild($role, $permission);
                }
            }
          return  '设置角色权限成功';
        }
        return $this->render('setaccess',['role'=>$role,'parent'=>$parent,'array'=>$array]);
    }

    private function _getTree($data){
        foreach($data as $key=>$val){
            $this->index+=1;
            if($val['tt-parent-id']==null){
                $this->str.="<tr data-tt-id=".$val['id'].">";}else{
                $this->str.="<tr data-tt-id=".$val['tt-parent-id'].'-'.$val['id']." data-tt-parent-id=".$val['tt-parent-id'].">";
            }
            $this->str.="<td>"."$this->index"."</td>";
            $this->str.="<td>". $val['id']."</td>";
            if(isset($val['children']) && !empty($val['children'])){
                $this->str.="<td class='yx-text-left1'><span class='folder zx_mg19'>".$val['name']."</span></td>";
            } else{
                $this->str.="<td class='yx-text-left1'><span class='file zx_mg19'>".$val['name']."</span></td>";
            }
            if($val['input']){
                $this->str.="<td class='yx-pt12'><input class='yx-switch' type='checkbox' value='".$val['id']."'checked /></td></tr>";
            }else{
                $this->str.="<td class='yx-pt12'><input class='yx-switch' type='checkbox' value='".$val['id']."'/></td></tr>";
            }

            if(isset($val['children'])&& !empty($val['children'])) $this->_getTree($val['children']);
        }
        return $this->str;
    }

    private function __getPermission($id){//在authitem中更新添加权限的同时，返回权限
        $menu_cache=Fun::cache('menu_branch_cache',false);
        if(isset($menu_cache[$id])){
            $menu_info=$menu_cache[$id];
            $str=!empty($menu_info['m'])?$menu_info['m'].'_'.$menu_info['c'].'_'.$menu_info['a']:$menu_info['c'].'_'.$menu_info['a'];
            if(!empty($menu_info['param'])){
                $param=Util::param2array($menu_info['param']);
                foreach($param as $k=>$v){
                    if(strpos($v,'$') == false)
                        $str .= '_'.$v;
                }
            }
            $auth = \Yii::$app->authManager;
            $permission=$auth->getPermission($str);//返回一个操作
            if($permission!==null)return $permission;
            $permission=$auth->createPermission($str);//创建新的操作对象
            $permission->description=$menu_info['name'];
            $auth->add($permission);//将操作添加到权限管理系统
            Fun::getSiteDb()->createCommand()->update('{{%auth_item}}',['menu_id'=>$id],['name'=>$str,'type'=>2])->execute();//更新auth_item中的menu_id
            return $permission;
        }

    }





}
